﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using NP.BPMReportPlatform.AuthorizationProcessesManager.Dtos;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.Entities.BPM_Process;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Microsoft.AspNetCore.Mvc;
using Magicodes.ExporterAndImporter.Core.Extension;
using RazorEngine.Compilation.ImpromptuInterface.InvokeExt;
using NP.BPMReportPlatform.Entities.BPM_Business;
using Volo.Abp.Data;
using NP.BPMReportPlatform.YJJSZHSQ.Dtos;
using System.Collections;
using Microsoft.EntityFrameworkCore;
using RazorEngine.Compilation.ImpromptuInterface.Optimization;
using NP.BPMReportPlatform.AuthorizationUserManager.Dtos;

namespace NP.BPMReportPlatform.AuthorizationProcessesManager
{
    /// <summary>
    /// 流程权限管理
    /// </summary>
    public class AuthorizationProcessesAppService : BPMReportPlatformAppService, IAuthorizationProcessesAppService
    {
        private readonly SqlSugarClient _db, _dbPlatform, _dbProcess, _dbEngine;
        private readonly ILogger<AuthorizationProcessesAppService> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sqlSugarAppService"></param>
        public AuthorizationProcessesAppService(ISqlSugarAppService sqlSugarAppService, ILogger<AuthorizationProcessesAppService> logger)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbProcess = sqlSugarAppService.GetProcessInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
        }

        /// <summary>
        /// 获取流程权限
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private async Task<List<string>> GetProcessPermission(GetUserAuthorizationProcessesInput input)
        {
            var userRole = await _dbProcess.Queryable<Role, UserRoleMapping>((r, ur) =>
               new JoinQueryInfos(JoinType.Inner, r.Id.Equals(ur.RoleId))).
               Where((r, ur) => r.IsEnable == 1 && (ur.EmployeeCode.Equals(input.EmployeeCode) || r.IsPublic == 1)
               && r.RoleType == (int)RoleEnum.Processes).Select(r => r).ToListAsync();

            var userOrgList = new List<string>();

            if (userRole.Any())
            {
                var isAdmin = userRole.Where(r => r.Name.ToLower().Equals("admin")).Any();
                if (isAdmin)
                {
                    return await _dbProcess.Queryable<AuthorizationProcessesSettings, Processes>((a, p) =>
                            new JoinQueryInfos(JoinType.Inner, a.ProcessCode.Equals(p.BTID))).
                            Where((a, p) => p.InUse == 1).Select((a, p) => p.BTID).Distinct().ToListAsync();
                }
            }

            var userOrg = await _dbPlatform.Queryable<Users>().Where(x => x.Status == 1 && x.WorkNumber.Equals(input.EmployeeCode)).Select(x => x.FullPathCode).FirstAsync();
            if (string.IsNullOrWhiteSpace(userOrg))
            {
                return new List<string>();
            }
            userOrgList.AddRange(userOrg.Split('_').ToList());

            var userRoleArray = userRole.Select(x => x.Id.ToString()).ToList();

            userOrgList.AddRange(userRoleArray);
            userOrgList.Add(input.EmployeeCode);

            var permissionCodeArray = userOrgList.ToArray();

            var rst = await _dbProcess.Queryable<AuthorizationProcessesSettings, Processes>
               ((a, p) => new JoinQueryInfos(JoinType.Inner, a.ProcessCode.Equals(p.BTID))).
               Where((a, p) => p.InUse == 1).
               Where((a, p) => SqlFunc.ContainsArray(permissionCodeArray, a.PermissionCode)).
               WhereIF(!string.IsNullOrWhiteSpace(input.ProcessCode), (a, p) => a.ProcessCode.Equals(input.ProcessCode)).
               WhereIF(input.ProcessId != null && input.ProcessId != Guid.Empty, (a, p) => p.ProcessId.Equals(input.ProcessId)).Select((a, p) => p.BTID).Distinct().ToListAsync();

            return rst;

        }

        /// <summary>
        /// 获取用户单个流程权限
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> GetSingleProcessPermission(GetUserAuthorizationProcessesInput input)
        {
            if (input.ProcessId == null || input.ProcessId == Guid.Empty)
            {
                return false;
            }

            var rst = await GetProcessPermission(input);

            return rst.Any() ? true : false;

        }

        /// <summary>
        /// 获取用户流程权限
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<string>> GetUserAuthorizationProcesses(string EmployeeCode)
        {
            return await GetProcessPermission(new GetUserAuthorizationProcessesInput() { EmployeeCode = EmployeeCode });
        }

        /// <summary>
        /// 获取微信用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<GetWechatUserOutput> GetWechatUser(GetWechatUserInput input)
        {
            var dbWechatUser = await _dbPlatform.Queryable<WeChatUser>().
                WhereIF(!string.IsNullOrWhiteSpace(input.UserName), x => x.UserName.Equals(input.UserName)).WhereIF(!string.IsNullOrWhiteSpace(input.UserName), x => x.UserName.Equals(input.UserName)).
                WhereIF(!string.IsNullOrWhiteSpace(input.UserLoginId), x => x.UserLoginId.Equals(input.UserLoginId)).
                WhereIF(!string.IsNullOrWhiteSpace(input.EmployeeCode), x => x.EmployeeCode.Equals(input.EmployeeCode)).
                WhereIF(!string.IsNullOrWhiteSpace(input.Phone), x => x.Phone.Equals(input.Phone)).FirstAsync();
            if (dbWechatUser != null)
            {
                var rst = ObjectMapper.Map<WeChatUser, GetWechatUserOutput>(dbWechatUser);
                return rst;
            }
            return new GetWechatUserOutput();

        }

        /// <summary>
        /// 获取流程信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<ProcessInfoOutput>> GetProcessList(ProcessInfoInput input)
        {
            RefAsync<int> totalCount = 0;
            var listQueryable = GetQueryable(input);
            var processList= await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            //返回结果
            return new PagedResultDto<ProcessInfoOutput>()
            {
                TotalCount = totalCount,
                Items = processList
            };
        }
        private ISugarQueryable<ProcessInfoOutput> GetQueryable(ProcessInfoInput input)
        {
            var listQueryable = _dbProcess.Queryable<Processes, AuthorizationProcessesSettings, ProcessResponsible>
                ((a, b, c) => new JoinQueryInfos(JoinType.Left, a.BTID.Equals(b.ProcessCode), JoinType.Left, a.ProcessId.Equals(c.ProcessId)))
                .WhereIF(!string.IsNullOrWhiteSpace(input.ProcessName), (a, b, c) => a.Name.Contains(input.ProcessName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.ProcessCode), (a, b, c) => a.BTID.Contains(input.ProcessCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessType), (a, b, c) => a.BusinessTypeName.Contains(input.BusinessType))
                .WhereIF(!string.IsNullOrEmpty(input.Enabled), (a, b, c) => a.InUse.Equals(input.Enabled))
                .WhereIF(!string.IsNullOrEmpty(input.PermissionCode), (a, b, c) => b.PermissionCode.Equals(input.PermissionCode))
                .Select((a, b, c) => new ProcessInfoOutput()
                {
                    ProcessId = a.ProcessId,
                    ReponsibleId = c.Id,
                    ProcessName = a.Name,
                    ProcessCode = a.BTID,
                    BusinessTypeName = a.BusinessTypeName,
                    Enabled = a.InUse.ToString(),
                    PlatformType = 1,
                    PlatformTypeName = "新平台",
                    ResponsiblePerson = c.ResponsiblePerson,
                    ResponsibleDepartment = c.ResponsibleDepartment,
                    ContactPerson = c.ContactPerson,
                    Developer = c.Developer,
                    Remark = c.Remark,
                    FormType = c.FormType,
                    StartDeviceType = c.StartDeviceType,
                    ApproveDeviceType = c.ApproveDeviceType,
                    ItemResponsiblePerson = c.ItemResponsiblePerson,
                    Email = c.Email,
                    CCEmail = c.CCEmail,
                    IsCanCallBack = c.IsCanCallBack,
                    IsSendApprovedEmail = c.IsSendApprovedEmail,
                    IsUseToDoEmail = c.IsUseToDoEmail,
                }).MergeTable().GroupBy(a => a.ProcessId);
            var listQueryable1 = _dbProcess.Queryable<ProcessesOld, AuthorizationProcessesSettings, ProcessResponsible, FlowCategory>
                ((a, b, c, d) => new JoinQueryInfos(JoinType.Left, a.BTID.Equals(b.ProcessCode), 
                JoinType.Left, a.ProcessId.Equals(c.ProcessId), 
                JoinType.Left, a.BusinessTypeName.Equals(d.Code)))
                .WhereIF(!string.IsNullOrWhiteSpace(input.ProcessName), (a, b, c, d) => a.Name.Contains(input.ProcessName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.ProcessCode), (a, b, c, d) => a.BTID.Contains(input.ProcessCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.BusinessType), (a, b, c, d) => d.Alias.Contains(input.BusinessType))
                .WhereIF(!string.IsNullOrEmpty(input.Enabled), (a, b, c, d) => a.InUse.Equals(input.Enabled))
                .WhereIF(!string.IsNullOrEmpty(input.PermissionCode), (a, b, c, d) => b.PermissionCode.Equals(input.PermissionCode))
                .Select((a, b, c, d) => new ProcessInfoOutput()
                {
                    ProcessId = a.ProcessId,
                    ReponsibleId = c.Id,
                    ProcessName = a.Name,
                    ProcessCode = a.BTID,
                    BusinessTypeName = d.Alias,
                    Enabled = a.InUse.ToString(),
                    PlatformType = 2,
                    PlatformTypeName = "旧平台",
                    ResponsiblePerson = c.ResponsiblePerson,
                    ResponsibleDepartment = c.ResponsibleDepartment,
                    ContactPerson = c.ContactPerson,
                    Developer = c.Developer,
                    Remark = c.Remark,
                    FormType = c.FormType,
                    StartDeviceType = c.StartDeviceType,
                    ApproveDeviceType = c.ApproveDeviceType,
                    ItemResponsiblePerson = c.ItemResponsiblePerson,
                    Email = c.Email,
                    CCEmail = c.CCEmail,
                    IsCanCallBack = c.IsCanCallBack,
                    IsSendApprovedEmail = c.IsSendApprovedEmail,
                    IsUseToDoEmail = c.IsUseToDoEmail,
                }).MergeTable().GroupBy(a => a.ProcessId);
            var query = _dbProcess.Union(listQueryable, listQueryable1)
                .WhereIF(!string.IsNullOrEmpty(input.PlatformType), x => x.PlatformType.Equals(input.PlatformType)).MergeTable();
            return query;
        }
        /// <summary>
        /// 导出流程信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<ProcessInfoOutput>> ExportProcessList(ProcessInfoInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            return listViewDto;
        }
        /// <summary>
        /// 编辑流程
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<string> EditProcessAsync(EditProcessInput input)
        {
            RefAsync<string> res = "编辑成功！";
            var entity = _dbProcess.Queryable<Processes>().Where(x => x.ProcessId.Equals(input.ProcessId)).First();
            if (entity == null)
            {
                var oldEntity = _dbProcess.Queryable<ProcessesOld>().Where(x => x.ProcessId.Equals(input.ProcessId)).First();
                if (oldEntity == null)
                {
                    throw new Exception("流程数据未找到！");
                }
                else
                {
                    try
                    {
                        _db.BeginTran();

                        oldEntity.InUse = input.Enabled;
                        await _dbProcess.Updateable(oldEntity).WhereColumns(x => x.ProcessId).ExecuteCommandAsync();
                        var processResponsible = _dbProcess.Queryable<ProcessResponsible>().Where(x => x.ProcessId.Equals(input.ProcessId)).First();
                        if (processResponsible == null)
                        {
                            var reponsible = new ProcessResponsible
                            {
                                Id = Guid.NewGuid(),
                                ProcessId = input.ProcessId,
                                ProcessCode = oldEntity.BTID,
                                ProcessName = oldEntity.Name,
                                ResponsiblePerson = input.ResponsiblePerson,
                                ResponsibleDepartment = input.ResponsibleDepartment,
                                ContactPerson = input.ContactPerson,
                                Developer = input.Developer,
                                Remark = input.Remark,
                                AddUserId = CurrentUser.Id.Value,
                                AddTime = DateTime.Now,
                                FormType = input.FormType,
                                StartDeviceType = input.StartDeviceType,
                                ApproveDeviceType = input.ApproveDeviceType,
                                ItemResponsiblePerson = input.ItemResponsiblePerson,
                                Email = input.Email,
                                CCEmail = input.CCEmail,
                                IsCanCallBack = input.IsCanCallBack,
                                IsSendApprovedEmail = input.IsSendApprovedEmail,
                                IsUseToDoEmail = input.IsUseToDoEmail,
                            };
                            await _dbProcess.Insertable(reponsible).ExecuteCommandAsync();
                        }
                        else
                        {
                            processResponsible.ResponsiblePerson = input.ResponsiblePerson;
                            processResponsible.ResponsibleDepartment = input.ResponsibleDepartment;
                            processResponsible.ContactPerson = input.ContactPerson;
                            processResponsible.Developer = input.Developer;
                            processResponsible.Remark = input.Remark;
                            processResponsible.UpdateUserId = CurrentUser.Id.Value;
                            processResponsible.UpdateTime = DateTime.Now;
                            processResponsible.FormType = input.FormType;
                            processResponsible.StartDeviceType = input.StartDeviceType;
                            processResponsible.ApproveDeviceType = input.ApproveDeviceType;
                            processResponsible.ItemResponsiblePerson = input.ItemResponsiblePerson;
                            processResponsible.Email = input.Email;
                            processResponsible.CCEmail = input.CCEmail;
                            processResponsible.ProcessCode = oldEntity.BTID;
                            processResponsible.ProcessName = oldEntity.Name;
                            processResponsible.IsCanCallBack = input.IsCanCallBack;
                            processResponsible.IsSendApprovedEmail = input.IsSendApprovedEmail;
                            processResponsible.IsUseToDoEmail = input.IsUseToDoEmail;
                            await _dbProcess.Updateable(processResponsible).WhereColumns(x => x.Id).ExecuteCommandAsync();
                        }

                        _db.CommitTran();
                    }
                    catch (Exception ex)
                    {
                        _db.RollbackTran();
                        throw new Exception(ex.Message);
                    }
                }
            }
            else
            {
                try
                {
                    _db.BeginTran();

                    entity.InUse = input.Enabled;
                    await _dbProcess.Updateable(entity).WhereColumns(x => x.ProcessId).ExecuteCommandAsync();
                    var processResponsible = _dbProcess.Queryable<ProcessResponsible>().Where(x => x.ProcessId.Equals(input.ProcessId)).First();
                    if (processResponsible == null)
                    {
                        var reponsible = new ProcessResponsible
                        {
                            Id = Guid.NewGuid(),
                            ProcessId = input.ProcessId,
                            ProcessCode = entity.BTID,
                            ProcessName = entity.Name,
                            ResponsiblePerson = input.ResponsiblePerson,
                            ResponsibleDepartment = input.ResponsibleDepartment,
                            ContactPerson = input.ContactPerson,
                            Developer = input.Developer,
                            Remark = input.Remark,
                            AddUserId = CurrentUser.Id.Value,
                            AddTime = DateTime.Now,
                            FormType = input.FormType,
                            StartDeviceType = input.StartDeviceType,
                            ApproveDeviceType = input.ApproveDeviceType,
                            ItemResponsiblePerson = input.ItemResponsiblePerson,
                            Email = input.Email,
                            CCEmail = input.CCEmail,
                            IsCanCallBack = input.IsCanCallBack,
                            IsSendApprovedEmail = input.IsSendApprovedEmail,
                            IsUseToDoEmail = input.IsUseToDoEmail,
                        };
                        await _dbProcess.Insertable(reponsible).ExecuteCommandAsync();
                    }
                    else
                    {
                        processResponsible.ResponsiblePerson = input.ResponsiblePerson;
                        processResponsible.ResponsibleDepartment = input.ResponsibleDepartment;
                        processResponsible.ContactPerson = input.ContactPerson;
                        processResponsible.Developer = input.Developer;
                        processResponsible.Remark = input.Remark;
                        processResponsible.UpdateUserId = CurrentUser.Id.Value;
                        processResponsible.UpdateTime = DateTime.Now;
                        processResponsible.FormType = input.FormType;
                        processResponsible.StartDeviceType = input.StartDeviceType;
                        processResponsible.ApproveDeviceType = input.ApproveDeviceType;
                        processResponsible.ItemResponsiblePerson = input.ItemResponsiblePerson;
                        processResponsible.Email = input.Email;
                        processResponsible.CCEmail = input.CCEmail;
                        processResponsible.ProcessCode = entity.BTID;
                        processResponsible.ProcessName = entity.Name;
                        processResponsible.IsCanCallBack = input.IsCanCallBack;
                        processResponsible.IsSendApprovedEmail = input.IsSendApprovedEmail;
                        processResponsible.IsUseToDoEmail = input.IsUseToDoEmail;
                        await _dbProcess.Updateable(processResponsible).WhereColumns(x => x.Id).ExecuteCommandAsync();
                    }

                    _db.CommitTran();
                }
                catch (Exception ex)
                {
                    _db.RollbackTran();
                    throw new Exception(ex.Message);
                }
            }
            return res;
        }

        /// <summary>
        /// 查询流程发起权限
        /// </summary>
        /// <param name="processCode"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PagedResultDto<AuthorizationProcessesSettingsDto>> GetAuthorizationProcessAsync(GetAuthorizationProcessesSettingsInput input)
        {
            RefAsync<int> totalCount = 0;
            var listQueryable = _dbProcess.Queryable<AuthorizationProcessesSettings>()
                .WhereIF(!string.IsNullOrWhiteSpace(input.ProcessCode), x => x.ProcessCode.Equals(input.ProcessCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.PermissionCode), x => x.PermissionCode.Equals(input.PermissionCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.PermissionName), x => x.PermissionName.Equals(input.PermissionName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Type), x => x.Type.Equals(input.Type))
                .Select(x => new AuthorizationProcessesSettingsDto()
                {
                    Id = x.Id,
                    ProcessCode = x.ProcessCode,
                    PermissionCode = x.PermissionCode,
                    PermissionName = x.PermissionName,
                    Type = x.Type,
                    PlatformType = x.PlatformType,
                }).MergeTable();
            var processList = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            //返回结果
            return new PagedResultDto<AuthorizationProcessesSettingsDto>()
            {
                TotalCount = totalCount,
                Items = processList
            };
        }

        /// <summary>
        /// 新增流程发起权限配置
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task AddAuthorizationProcessAsync(AuthorizationProcessesSettings input)
        {
            if (_dbProcess.Queryable<AuthorizationProcessesSettings>()
                .Where(q => q.ProcessCode.Equals(input.ProcessCode))
                .Where(q => q.PermissionCode.Equals(input.PermissionCode))
                .Where(q => q.Type.Equals(input.Type))
                .Where(q => q.PlatformType.Equals(input.PlatformType)).Any())
            {
                throw new Exception("数据已存在");
            }
            return _dbProcess.Insertable(input).ExecuteCommandAsync();
        }

        /// <summary>
        /// 编辑流程发起权限配置
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task EditAuthorizationProcessAsync(AuthorizationProcessesSettings input)
        {
            if (_dbProcess.Queryable<AuthorizationProcessesSettings>()
               .Where(q => q.ProcessCode.Equals(input.ProcessCode))
               .Where(q => q.PermissionCode.Equals(input.PermissionCode))
               .Where(q => q.Type.Equals(input.Type))
               .Where(q => !q.Id.Equals(input.Id))
               .Where(q => q.PlatformType.Equals(input.PlatformType)).Any())
            {
                throw new Exception("数据已存在");
            }
            return _dbProcess.Updateable(input).WhereColumns(q => q.Id).ExecuteCommandAsync();
        }
        /// <summary>
        /// 编辑流程
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task EditProcess(AuthorizationProcessesSettings input)
        {
            if (_dbProcess.Queryable<AuthorizationProcessesSettings>()
               .Where(q => q.ProcessCode.Equals(input.ProcessCode))
               .Where(q => q.PermissionCode.Equals(input.PermissionCode))
               .Where(q => q.Type.Equals(input.Type))
               .Where(q => !q.Id.Equals(input.Id))
               .Where(q => q.PlatformType.Equals(input.PlatformType)).Any())
            {
                throw new Exception("数据已存在");
            }
            return _dbProcess.Updateable(input).WhereColumns(q => q.Id).ExecuteCommandAsync();
        }

        /// <summary>
        /// 删除流程发起权限配置
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task DeleteAuthorizationProcessAsync(Guid id)
        {
            return _dbProcess.Deleteable<AuthorizationProcessesSettings>().Where(x => x.Id.Equals(id)).ExecuteCommandAsync();
        }

        /// <summary>
        /// 验证是否维护了负责人信息
        /// </summary>
        /// <returns></returns>
        public async Task<bool> CheckResponsible(Guid ProcessId)
        {
            return await _dbProcess.Queryable<ProcessResponsible>().AnyAsync(x => x.ProcessId.Equals(ProcessId) &&
                !SqlFunc.IsNullOrEmpty(x.ResponsiblePerson) && !SqlFunc.IsNullOrEmpty(x.ResponsibleDepartment) &&
                !SqlFunc.IsNullOrEmpty(x.ContactPerson) && !SqlFunc.IsNullOrEmpty(x.Developer) &&
                !SqlFunc.IsNullOrEmpty(x.ApproveDeviceType) && !SqlFunc.IsNullOrEmpty(x.ItemResponsiblePerson) &&
                !SqlFunc.IsNullOrEmpty(x.StartDeviceType) && (!x.StartDeviceType.Equals("T") ||
                !SqlFunc.IsNullOrEmpty(x.FormType) && x.StartDeviceType.Equals("T")) &&
                !SqlFunc.IsNullOrEmpty(x.Email));
        }

        /// <summary>
        /// 老BPM根据用户工号获取授权流程ID列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<GetUserProcessAuthForOldBPMOutput>> GetUserAuthProcessId(string WorkNumber)
        {
            var userOrgList = new List<string>();
            var user = await _dbPlatform.Queryable<Users>().Where(x => x.Status == 1 && 
                (x.WorkNumber.Equals(WorkNumber) || x.UserLoginId.Equals(WorkNumber))).FirstAsync();
            if (user == null)
            {
                return new List<GetUserProcessAuthForOldBPMOutput>();
            }
            if (!string.IsNullOrWhiteSpace(user.FullPathCode))
            {
                userOrgList.AddRange(user.FullPathCode.Split('_').ToList());
            }
            else
            {
                userOrgList.Add("50077099");
            }

            var userRole = await _dbProcess.Queryable<Role, UserRoleMapping>((r, ur) =>
               new JoinQueryInfos(JoinType.Inner, r.Id.Equals(ur.RoleId))).
               Where((r, ur) => r.IsEnable == 1 && (ur.EmployeeCode.Equals(user.WorkNumber) || r.IsPublic == 1)
               && r.RoleType == (int)RoleEnum.Processes).Select(r => r).ToListAsync();

            if (userRole.Any(r => r.Name.ToLower().Equals("admin")))
            {
                var query = await _dbProcess.Queryable<AuthorizationProcessesSettings, ProcessesOld, FlowCategory>((x, p, f) =>
                    new JoinQueryInfos(
                        JoinType.Inner, x.ProcessCode.Equals(p.BTID) && p.InUse.Equals(1) && !p.BusinessTypeName.Equals("ThirdFlow"),
                        JoinType.Left, p.BusinessTypeName.Equals(f.Code)))
                    .Where((x, p, f) => x.PlatformType.Equals(2))
                    .Select((x, p, f) => new GetUserProcessAuthForOldBPMOutput
                    {
                        ProcessId = x.ProcessCode,
                        ProcessName = p.Name,
                        TypeName = f == null ? "" : f.Alias
                    }).ToListAsync();
                return query.GroupBy(x => x.ProcessId).Select(x => x.First()).ToList();
            }
            else
            {
                var userRoleArray = userRole.Select(x => x.Id.ToString()).ToList();

                var query = await _dbProcess.Queryable<AuthorizationProcessesSettings, ProcessesOld, FlowCategory>((x, p, f) =>
                    new JoinQueryInfos(
                        JoinType.Inner, x.ProcessCode.Equals(p.BTID) && p.InUse.Equals(1) && !p.BusinessTypeName.Equals("ThirdFlow"),
                        JoinType.Left, p.BusinessTypeName.Equals(f.Code)))
                    .Where((x, p, f) =>
                        x.PlatformType.Equals(2) &&
                        (x.Type.Equals(3) && (x.PermissionCode.Equals(WorkNumber) || x.PermissionCode.Equals(user.UserLoginId)) ||
                        x.Type.Equals(2) && userRoleArray.Contains(x.PermissionCode) ||
                        x.Type.Equals(1) && userOrgList.Contains(x.PermissionCode)))
                    .Select((x, p, f) => new GetUserProcessAuthForOldBPMOutput
                    {
                        ProcessId = x.ProcessCode,
                        ProcessName = p.Name,
                        TypeName = f == null ? "" : f.Alias
                    }).MergeTable().GroupBy(x => x.ProcessId).ToListAsync();
                return query.GroupBy(x => x.ProcessId).Select(x => x.First()).ToList();
            }
        }
    }
}
